package icu.luoxi.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import icu.luoxi.mapper.master.ScheduledTaskMapper;
import icu.luoxi.model.entity.ScheduledTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

/**
 * @author Cao Jiwen
 * @date 2025/5/6 11:27
 * @description 动态任务调度服务
 */
@Service
public class DynamicTaskSchedulerService {

    private final Map<String, ScheduledFuture<?>> taskFutureMap = new HashMap<>();

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    @Autowired
    private ScheduledTaskMapper taskMapper;

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void init() {
        // 应用启动时加载所有启用的任务
        List<ScheduledTask> enabledTasks = taskMapper.selectList(new QueryWrapper<ScheduledTask>().eq("task_status", 1));
        enabledTasks.forEach(this::scheduleTask);
    }

    /**
     * 启动任务
     */
    @Transactional
    public boolean startTask(String taskKey) {
        ScheduledTask task = taskMapper.selectOne(new QueryWrapper<ScheduledTask>().eq("task_key", taskKey));
        if (task == null || task.getTaskStatus() == 1) {
            return false;
        }
        taskMapper.updateTaskStatus(taskKey, 1);
        scheduleTask(task);
        return true;
    }

    /**
     * 停止任务
     */
    @Transactional
    public boolean stopTask(String taskKey) {
        ScheduledTask task = taskMapper.selectOne(new QueryWrapper<ScheduledTask>().eq("task_key", taskKey));
        if (task == null || task.getTaskStatus() == 0) {
            return false;
        }
        cancelTask(taskKey);
        taskMapper.updateTaskStatus(taskKey, 0);
        return true;
    }

    /**
     * 更新任务执行周期
     */
    @Transactional
    public boolean updateTaskCron(String taskId) {
        ScheduledTask task = taskMapper.selectOne(new QueryWrapper<ScheduledTask>().eq("id", taskId));
        if (task == null) {
            return false;
        }
        String newCron = task.getCronExpression();
        String taskKey = task.getTaskKey();
        // 先取消旧任务
        cancelTask(taskKey);
        // 如果任务原本是启用的，则重新启动
        if (task.getTaskStatus() == 1) {
            task.setCronExpression(newCron);
            scheduleTask(task);
        }

        return true;
    }

    /**
     * 调度任务
     */
    private void scheduleTask(ScheduledTask task) {
        try {
            DynamicTask dynamicTask = (DynamicTask) applicationContext.getBean(Class.forName(task.getTaskClass()));
            ScheduledFuture<?> future = taskScheduler.schedule(
                    () -> {
                        try {
                            dynamicTask.execute();
                        } catch (Exception e) {
                            // 记录任务执行异常
                            e.printStackTrace();
                        }
                    },
                    new CronTrigger(task.getCronExpression())
            );

            taskFutureMap.put(task.getTaskKey(), future);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Task class not found: " + task.getTaskClass(), e);
        }
    }

    /**
     * 取消任务
     */
    private void cancelTask(String taskKey) {
        ScheduledFuture<?> future = taskFutureMap.get(taskKey);
        if (future != null) {
            future.cancel(true);
            taskFutureMap.remove(taskKey);
        }
    }

    /**
     * 获取所有任务状态
     */
    public List<ScheduledTask> getAllTasks() {
        return taskMapper.selectList(new QueryWrapper<ScheduledTask>());
    }
}
